package top.fullj.remoting;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * @author bruce.wu
 * @since 2022/2/16 10:01
 */
public class FutureValue<T> implements Future<T> {

    private volatile T value;

    private final CountDownLatch latch = new CountDownLatch(1);

    public synchronized void setValue(T value) {
        if (isDone()) {
            return;
        }
        this.value = value;
        latch.countDown();
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        return false;
    }

    @Override
    public boolean isCancelled() {
        return false;
    }

    @Override
    public boolean isDone() {
        return this.value != null;
    }

    @Override
    public T get() throws InterruptedException {
        latch.await();
        return value;
    }

    @SuppressWarnings("NullableProblems")
    @Override
    public T get(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
        if (!latch.await(timeout, unit)) {
            throw new TimeoutException();
        }
        return value;
    }

}
